---
title: View Transitions
description: >-
  Habilita una navegación fluida entre páginas en Astro con las view transitions.
i18nReady: true
---
import Since from '~/components/Since.astro'

Astro admite **view transitions opcionales por página** con solo unas pocas líneas de código. Las view transitions actualizan el contenido de tu página sin recargar la navegación completa normal del navegador, lo que proporciona animaciones fluidas entre páginas.

Astro ofrece un componente de enrutamiento `<ViewTransitions />` que se puede agregar dentro del `<head>` de una sola página para controlar las transiciones de página mientras navegas hacia otra página. Proporciona un enrutador ligero del lado del cliente que [intercepta la navegación](#proceso-de-navegación-del-lado-del-cliente) y te permite personalizar la transición entre páginas.

Agrega este componente a un componente `.astro` reutilizable, como un encabezado común o un diseño, para lograr [transiciones animadas de página en todo tu sitio (modo SPA)](#view-transitions-completas-en-todo-el-sitio-modo-spa).

El soporte de las view transitions en Astro está impulsado por la nueva API del navegador [View Transitions](https://developer.chrome.com/docs/web-platform/view-transitions/) y también incluye:

- Algunas [opciones de animación integradas](#directivas-de-animación-integradas), como `fade`, `slide` y `none`.
- Soporte para animaciones de navegación hacia adelante y hacia atrás.
- La capacidad de [personalizar completamente todos los aspectos de la animación de transición](#personalizando-animaciones) y crear tus propias animaciones.
- La opción de [impedir la navegación del lado del cliente para enlaces que no sean de página](#previniendo-la-navegación-del-lado-del-cliente).
- [Control sobre el comportamiento de respaldo](#control-de-respaldo) para navegadores que aún no admiten las API de View Transitions.
- Soporte automático para [`prefers-reduced-motion`](#prefers-reduced-motion).

:::note
Por defecto, cada página utilizará la navegación normal del navegador, ocupando toda la página. Debes optar por ver las view transitions y puedes usarlas por página o en todo el sitio.
:::

## Agregando las View Transitions a una página

Opta por utilizar view transitions en páginas individuales importando y añadiendo el componente de enrutamiento `<ViewTransitions />` dentro del `<head>` en cada página deseada.

```astro title="src/pages/index.astro" ins={2,7}
---
import { ViewTransitions } from 'astro:transitions';
---
<html lang="es">
  <head>
    <title>Mi página de inicio</title>
    <ViewTransitions />
  </head>
  <body>
    <h1>¡Bienvenido a mi sitio web!</h1>
  </body>
</html>
```

## View transitions completas en todo el sitio (modo SPA)

Importa y agrega el componente `<ViewTransitions />` a tu componente `<head>` común o de diseño compartido. Astro creará animaciones de página predeterminadas basadas en las similitudes entre la página antigua y la nueva, y también proporcionará un comportamiento de respaldo para los navegadores que no lo admitan.

El ejemplo a continuación muestra cómo agregar las animaciones de navegación de página predeterminadas de Astro en todo el sitio, incluida la opción de control de respaldo predeterminado para navegadores que no las admiten, importando y agregando este componente a un componente `<CommonHead />` de Astro:

```astro title="src/components/CommonHead.astro" ins={2,12}
---
import { ViewTransitions } from 'astro:transitions';
---
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />

<!-- Etiquetas Meta Primarias -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />

<ViewTransitions />
```

¡No es necesario realizar ninguna otra configuración para habilitar la navegación predeterminada del lado del cliente en Astro!

Utiliza [directivas de transición](#directivas-de-transición) o [anula la navegación predeterminada del lado del cliente](#previniendo-la-navegación-del-lado-del-cliente) en elementos individuales para un control más preciso.

## Directivas de transición

Astro asignará automáticamente a los elementos encontrados tanto en la página antigua como en la nueva un `view-transition-name` compartido y único. Esta pareja de elementos coincidentes es inferida por el tipo de elemento y su ubicación en el DOM.

Utiliza las directivas opcionales `transition:*` en los elementos de la página dentro de tus componentes `.astro` para un control más fino sobre la animación de transición de la página durante la navegación.

- `transition:name`: Te permite anular la coincidencia de elementos predeterminada de Astro para la animación del contenido antiguo/nuevo y [especificar un nombre de transición](#nombrando-una-transición) para asociar un par de elementos DOM.
- `transition:animate`: Te permite modificar la animación predeterminada de Astro mientras reemplaza el elemento antiguo por el nuevo especificando un tipo de animación. Utiliza las [directivas de animación integradas](#directivas-de-animación-integradas) de Astro o [crea animaciones de transición personalizadas](#personalizando-animaciones).
- `transition: persist`: Te permite anular el reemplazo predeterminado de los elementos antiguos por los nuevos de Astro y, en su lugar, [persistir los componentes y elementos HTML](#manteniendo-el-estado) al navegar a otra página.


### Nombrando una transición

En algunos casos, es posible que desees o necesites identificar los elementos de transición de vista correspondientes tú mismo. Puedes especificar un nombre para un par de elementos utilizando la directiva `transition:name`.

```astro title="src/pages/old-page.astro"
<aside transition:name="hero">
```

```astro title="src/pages/new-page.astro"
<aside transition:name="hero">
```

Ten en cuenta que el valor proporcionado `transition:name` solo se puede utilizar una vez en cada página. Establece esto manualmente solo cuando Astro no pueda inferir un nombre adecuado por sí mismo, o para un control más fino sobre los elementos coincidentes.

### Manteniendo el estado

<p><Since v="2.10.0" /></p>

Puedes persistir componentes y elementos HTML (en lugar de reemplazarlos) a través de las navegaciones de página utilizando la directiva `transition:persist`.

Por ejemplo, el siguiente `<video>` continuará reproduciéndose a medida que navegas a otra página que contiene el mismo elemento de video. Esto funciona tanto para la navegación hacia adelante como hacia atrás.

```astro title="src/components/Video.astro" "transition:persist"
<video controls="" autoplay="" transition:persist>
	<source src="https://ia804502.us.archive.org/33/items/GoldenGa1939_3/GoldenGa1939_3_512kb.mp4" type="video/mp4">
</video>
```

También puedes colocar la directiva en una [isla de Astro](/es/concepts/islands/) (un componente de framework UI con una directiva [`client:`](/es/reference/directives-reference/#directivas-del-cliente)). Si ese componente existe en la siguiente página, la isla de la página antigua **con su estado actual** continuará mostrándose, en lugar de reemplazarla con la isla de la nueva página.

En el siguiente ejemplo, el estado interno del componente del recuento no se restablecerá cuando se navegue hacia adelante y hacia atrás por páginas que contengan el componente `<Counter />` con el atributo `transition:persist`.

```astro title="components/Header.astro" "transition:persist"
<Counter client:load transition:persist initialCount={5} />
```

También puedes [identificar manualmente los elementos correspondientes](#nombrando-una-transición) si la isla/elemento está en un componente diferente entre las dos páginas.

```astro title="src/pages/old-page.astro" "Video" 'transition:name="media-player"'
<Video controls="" autoplay="" transition:name="media-player" transition:persist />
```

```astro title="src/pages/new-page.astro" "MyVideo" 'transition:name="media-player"'
<MyVideo controls="" autoplay="" transition:name="media-player" transition:persist />
```

Una alternativa práctica, `transition:persist` puede tomar un nombre de transición como valor.

```astro title="src/pages/index.astro" '="media-player"'
<video controls="" autoplay="" transition:persist="media-player">
```

#### `transition:persist-props`
<p><Since v="4.5.0" /></p>

Esto te permite controlar si los props de una isla deben persistir o no tras la navegación.

Por defecto, cuando se añade `transition:persist` a una isla, el estado se mantiene durante la navegación, pero el componente se vuelve a renderizar con nuevos props. Esto es útil, por ejemplo, cuando un componente recibe props específicos de la página, como el `title` de la página actual.

Puede anular este comportamiento con `transition:persist-props`. Al añadir esta directiva se conservarán los accesorios existentes de una isla (no se volverá a renderizar con nuevos valores) además de mantener su estado existente.

### Directivas de animación integradas

Astro viene con algunas animaciones integradas para anular la transición `fade` predeterminada. Agrega la directiva `transition:animate` a elementos individuales para personalizar el comportamiento de transiciones específicas.

- `fade` (por defecto): Una animación de fundido cruzado opinionada. El contenido antiguo se desvanece y el nuevo contenido se desvanece al aparecer.
- `initial`: Optar por no usar la animación de fundido cruzado opinionada de Astro y en su lugar utilizar el estilo predeterminado del navegador.
- `slide`: Una animación donde el contenido antiguo se desliza hacia la izquierda y el nuevo contenido se desliza desde la derecha. En la navegación hacia atrás, las animaciones son opuestas.
- `none`: Desactiva las animaciones predeterminadas del navegador. Úsalo en el elemento `<html>` de una página para desactivar el fade predeterminado para cada elemento en la página.

Combina directivas para tener un control total sobre la animación de tu página. Establece un valor predeterminado para la página en el elemento `<html>`, y anúlalo en los elementos individuales que desees.

El siguiente ejemplo produce una animación de deslizamiento para el contenido del cuerpo, al mismo tiempo que desactiva la animación de fundido predeterminada del navegador para el resto de la página:

```astro
---
import CommonHead from '../components/CommonHead.astro';
---

<html transition:animate="none">
  <head>
    <CommonHead />
  </head>
  <body>
    <header>
      ...
    </header>
    <!-- Anula la configuración predeterminada de tu página en un solo elemento -->
    <main transition:animate="slide">
      ...
    </main>
  </body>
</html>
```

### Personalizando Animaciones

Puedes personalizar todos los aspectos de una transición utilizando las propiedades de animación de CSS.

Para personalizar una animación incorporada, primero importa la animación desde `astro:transitions`, y luego proporciona opciones de personalización.

El ejemplo a continuación personaliza la duración de la animación incorporada `fade`:

```astro
---
import { fade } from 'astro:transitions';
---

<header transition:animate={fade({ duration: '0.4s' })}>
```

También puedes definir tus propias animaciones para usar con `transition:animate`, definiendo tanto el comportamiento hacia adelante como hacia atrás, así como las páginas nuevas y antiguas, de acuerdo con los siguientes tipos:

```ts
export interface TransitionAnimation {
  name: string; // El nombre del keyframe
  delay?: number | string;
  duration?: number | string;
  easing?: string;
	fillMode?: string;
	direction?: string;
}

export interface TransitionAnimationPair {
	old: TransitionAnimation | TransitionAnimation[];
	new: TransitionAnimation | TransitionAnimation[];
}

export interface TransitionDirectionalAnimations {
	forwards: TransitionAnimationPair;
	backwards: TransitionAnimationPair;
}
```

El siguiente ejemplo muestra todas las propiedades necesarias para definir una animación personalizada de `fade`:

```astro
---
const anim = {
  old: {
    name: 'fadeIn',
    duration: '0.2s',
    easing: 'linear',
    fillMode: 'forwards',
  },
  new: {
    name: 'fadeOut',
    duration: '0.3s',
    easing: 'linear',
    fillMode: 'backwards',
  }
};

const myFade = {
	forwards: anim,
	backwards: anim,
};
---

<header transition:animate={myFade}> ... </header>
```

## Controlar el enrutador

El enrutador `<ViewTransitions />` maneja la navegación escuchando:

- Los clics en elementos `<a>`.
- Eventos de navegación hacia atrás y hacia adelante.

Las siguientes opciones te permiten controlar aún más cuándo ocurre la navegación dentro del enrutador:

- `data-astro-reload`: un atributo de la etiqueta `<a>` para [forzar una navegación de página completa](#previniendo-la-navegación-del-lado-del-cliente).
- `data-astro-history="auto | push | replace"`: un atributo de la etiqueta `<a>` para [controlar el historial del navegador](#reemplazar-entradas-en-el-historial-del-navegador).
- `navigate(href, options)`: un método disponible para cualquier script o componente cliente para [desencadenar la navegación](#desencadenar-la-navegación).

### Previniendo la navegación del lado del cliente

Existen casos en los que no se puede navegar a través del enrutamiento del lado del cliente ya que ambas páginas involucradas deben utilizar el enrutador `<ViewTransitions />` para evitar una recarga de página completa. También puede que no desees la navegación del lado del cliente en cada cambio de navegación y prefieras una navegación de página tradicional en rutas selectas en su lugar.

Puedes optar por no utilizar la navegación del lado del cliente de manera selectiva para cada enlace añadiendo el atributo `data-astro-reload` a cualquier etiqueta `<a>` o `<form>`. Este atributo anulará cualquier componente `<ViewTransitions />` existente y, en su lugar, provocará una recarga del navegador durante la navegación.

El siguiente ejemplo muestra cómo evitar la navegación del lado del cliente al navegar a un artículo desde la página de inicio únicamente. Esto aún te permite tener animaciones en elementos compartidos, como una imagen destacada, al navegar a la misma página desde una página de listado de artículos:

```astro title="src/pages/index.astro"
<a href="/articles/emperor-penguins" data-astro-reload>
```

```astro title="src/pages/articles.astro"
<a href="/articles/emperor-penguins">
```

Los enlaces con el atributo `data-astro-reload` serán ignorados por el enrutador y se producirá una navegación de página completa.

### Desencadenar la navegación

También puedes desencadenar la navegación del lado del cliente a través de eventos que normalmente no son escuchados por el enrutador `<ViewTransitions />` utilizando `navigate`. Esta función del módulo `astro:transitions/client` se puede utilizar en scripts y en componentes del framework que se hidratan con una [directiva de cliente](/es/reference/directives-reference/#directivas-del-cliente).

El siguiente ejemplo muestra un componente de Astro que lleva al visitante a otra página que selecciona desde un menú:
```astro title="src/components/Form.astro"
<script>
  import { navigate } from 'astro:transitions/client';
  // Navega a la opción seleccionada automáticamente.
  document.querySelector('select').onchange = (ev) => {
    let href = ev.target.value;
    navigate(href);
  };
</script>
<select>
  <option value="/play">Jugar</option>
  <option value="/blog">Blog</option>
  <option value="/about">Acerca de</option>
  <option value="/contact">Contacto</option>
</select>
```
```astro title="src/pages/index.astro"
---
import Form from "../components/Form.astro";
import { ViewTransitions } from "astro:transitions";
---
<html>
	<head>
		<ViewTransitions />
	</head>
	<body>
		<Form />
	</body>
</html>
```
El siguiente ejemplo implementa lo mismo usando `navigate()` en un componente `<Form />` de React:

```js title="src/components/Form.jsx"
import { navigate } from "astro:transitions/client";

export default function Form() {
  return (
    <select onChange={(e) => navigate(e.target.value)}>
      <option value="/play">Jugar</option>
      <option value="/blog">Blog</option>
      <option value="/about">Acerca de</option>
      <option value="/contact">Contacto</option>
    </select>
  );
}
```
El componente `<Form />` puede ser renderizado en una página de Astro que utiliza el enrutador `<ViewTransitions />`, con una directiva del cliente:

```astro title="src/pages/index.astro"
---
import Form from "../components/Form.jsx";
import { ViewTransitions } from "astro:transitions";
---
<html>
	<head>
		<ViewTransitions />
	</head>
	<body>
		<Form client:load />
	</body>
</html>
```

El método `navigate` toma los siguientes argumentos:

- `href` (obligatorio) - La nueva página a la que se va a navegar.
- `options` - Un objeto opcional con las siguientes propiedades:
	- `history`: `'push'` | `'replace'` | `'auto'`
		- `'push'`: el enrutador utilizará `history.pushState` para crear una nueva entrada en el historial del navegador.
		- `'replace'`: el enrutador utilizará `history.replaceState` para actualizar la URL sin agregar una nueva entrada en la navegación.
		- `'auto'` (por defecto): el enrutador intentará utilizar `history.pushState`, pero si la URL no es una que se pueda transicionar, la URL actual permanecerá sin cambios en el historial del navegador.
    - `formData`: Un objeto FormData para solicitudes `POST`.

Para navegar hacia atrás y hacia delante por el historial del navegador, puedes combinar `navigate()` con las funciones integradas `history.back()`, `history.forward()` e `history.go()` del navegador. Si `navigate()` es llamado durante la renderización del lado del servidor de tu componente, no tendrá efecto alguno.

### Reemplazar entradas en el historial del navegador

Normalmente, cada vez que navegas, se crea una nueva entrada en el historial del navegador. Esto permite la navegación entre páginas utilizando los botones `atrás` y `adelante` del navegador.

El enrutador `<ViewTransitions />` te permite sobrescribir las entradas del historial al agregar el atributo `data-astro-history` a cualquier etiqueta `<a>` individual.

El atributo `data-astro-history` puede establecerse en los mismos tres valores que la [opción `history` de la función `navigate()`](#desencadenar-la-navegación):

`data-astro-history`: `'push'` | `'replace'` | `'auto'`
- `'push'`: el enrutador utilizará `history.pushState` para crear una nueva entrada en el historial del navegador.
- `'replace'`: el enrutador utilizará `history.replaceState` para actualizar la URL sin agregar una nueva entrada en la navegación.
- `'auto'` (por defecto): el enrutador intentará utilizar `history.pushState`, pero si la URL no se puede transicionar, la URL actual se mantendrá sin cambios en el historial del navegador.

El siguiente ejemplo navega a la página `/main`, pero no agrega una nueva entrada al historial de navegación. En cambio, reutiliza la entrada actual en el historial (`/confirmation`) y la sobrescribe.

```astro title="src/pages/confirmation.astro"
<a href="/main" data-astro-history="replace">
```

Esto tiene el efecto de que si retrocedes desde la página `/main`, el navegador no mostrará la página `/confirmation`, sino la página anterior a ella.

### Transiciones con formularios

<p><Since v="4.0.0" /></p>

El enrutador `<ViewTransitions />` activará transiciones en la página desde elementos `<form>`, admitiendo tanto peticiones `GET` como `POST`.

Por defecto, Astro envía los datos de tu formulario como `multipart/form-data` cuando el atributo `method` está configurado como `POST`. Si deseas que coincida con el comportamiento predeterminado de los navegadores web, utiliza el atributo `enctype` para enviar tus datos codificados como `application/x-www-form-urlencoded`:

```astro title="src/components/Form.astro"
<form action="/contact" method="POST" enctype="application/x-www-form-urlencoded">
  <!-- -->
</form>
```

Puedes optar por excluir las transiciones del enrutador en formularios individuales mediante el atributo `data-astro-reload`:

```astro title="src/components/Form.astro"
<form action="/contact" data-astro-reload>
  <!-- -->
</form>
```

## Control de respaldo

El enrutador `<ViewTransitions />` funciona mejor en navegadores que admiten las View Transitions (p.ej. navegadores basados en Chromium), pero también incluye soporte predeterminado de respaldo para otros navegadores. Incluso si el navegador no admite la API de View Transitions, Astro seguirá proporcionando navegación en el navegador utilizando una de las opciones de respaldo para obtener una experiencia comparable.

Puedes anular el soporte de respaldo predeterminado de Astro agregando una propiedad `fallback` en el componente `<ViewTransitions />` y estableciéndolo en `swap` o `none`:

- `animate` (predeterminado, recomendado) - Astro simulará view transitions utilizando atributos personalizados antes de actualizar el contenido de la página.
- `swap` - Astro no intentará animar la página. En su lugar, la página antigua será reemplazada inmediatamente por la nueva.
- `none` - Astro no realizará ninguna transición animada de página. En su lugar, obtendrás navegación de página completa en navegadores que no admitan esta función.

```astro
---
import { ViewTransitions } from 'astro:transitions';
---
<title>Mi sitio</title>

<ViewTransitions fallback="swap" />
```

:::note[Limitaciones conocidas]
La animación del navegador `initial` no es simulada por Astro. Por lo tanto, cualquier elemento que utilice esta animación no será animado.
:::

## Proceso de navegación del lado del cliente

Cuando se utiliza el enrutador `<ViewTransitions />`, se siguen los siguientes pasos para llevar a cabo la navegación del lado del cliente en Astro:

1. Un visitante de tu sitio desencadena la navegación mediante cualquiera de las siguientes acciones:
    - Haciendo clic en una etiqueta `<a>` que enlaza internamente a otra página de tu sitio.
    - Haciendo clic en el botón de retroceso.
    - Haciendo clic en el botón de avance.
2. El enrutador comienza a buscar la siguiente página.
3. El enrutador agrega el atributo `data-astro-transition` al elemento HTML con un valor de `'forward'` o `'back'` según corresponda.
4. El enrutador llama a `document.startViewTransition`. Esto desencadena el propio [proceso de transición de vista](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API#the_view_transition_process) del navegador. Es importante destacar que el navegador captura una captura de pantalla del estado actual de la página.
5. Dentro del callback de `startViewTransition`, el enrutador realiza un __intercambio__, que consta de la siguiente secuencia de eventos:

    - El contenido de `<head>` se intercambia, manteniendo algunos elementos:
        - Los nodos DOM de las hojas de estilo se mantienen si existen en la nueva página, para evitar el parpadeo de contenido no estilizado (FOUC).
        - Los scripts se mantienen si existen en la nueva página.
        - Cualquier otro elemento de `<head>` con `transition:persist` se mantiene si hay un elemento correspondiente en la nueva página.

    - `<body>` se reemplaza completamente con el cuerpo de la nueva página.

    - Los elementos marcados con `transition:persist` se trasladan al nuevo DOM si existen en la nueva página.

    - La posición de desplazamiento se restaura si es necesario.

    - Se desencadena el evento `astro:after-swap` en el `document`. Esto marca el final del proceso de __intercambio__.

6. El enrutador espera a que se carguen las nuevas hojas de estilo antes de resolver la transición.
7. El enrutador ejecuta cualquier nuevo script agregado a la página.
8. Se dispara el evento `astro:page-load`. Esto marca el final del proceso de navegación.

## Comportamiento del script con view transitions

Al añadir view transitions a un proyecto de Astro existente, es posible que algunos de tus scripts ya no se vuelvan a ejecutar tras la navegación por la página, como ocurría con las actualizaciones de página completa del navegador. Utiliza la siguiente información para asegurarte de que tus scripts se ejecutan como se espera.

### Orden del Script

Al navegar entre páginas con el componente `<ViewTransitions />`, los scripts se ejecutan en orden secuencial para ajustarse al comportamiento del navegador. 

### Reejecución del script

Los [Bundled module scripts](/es/guides/client-side-scripts/#procesamiento-de-scripts), que son los scripts por defecto en Astro, sólo se ejecutan una vez. Después de la ejecución inicial serán ignorados, incluso si el script existe en la nueva página después de una transición.

A diferencia de los scripts de módulos empaquetados, los [scripts inline](/es/guides/client-side-scripts/#optar-por-no-procesar) pueden volver a ejecutarse durante la visita de un usuario a un sitio si existen en una página que se visita varias veces. Los scripts inline también pueden volver a ejecutarse cuando un visitante navega a una página sin el script y luego vuelve a una con el script.

#### `data-astro-rerun`

<p><Since v="4.5.0" /></p>

Para forzar a los scripts inline a reejecutarse después de cada transición, añade la propiedad `data-astro-rerun`. Al añadir cualquier atributo a un script también se añade implícitamente `is:inline`, por lo que esto sólo está disponible para scripts que no están empaquetados y procesados por Astro.


```astro
<script is:inline data-astro-rerun>...</script>
```

Para garantizar que un script se ejecuta cada vez que se carga una página durante la navegación del lado del cliente, debe ser ejecutado por un [evento del ciclo de vida](#eventos-del-ciclo-de-vida). Por ejemplo, los escuchadores de eventos para `DOMContentLoaded` pueden sustituirse por el evento de ciclo de vida [`astro:page-load`](/es/guides/view-transitions/#astropage-load).

Si tienes código que establece un estado global en un script inline, este estado necesitará tener en cuenta que el script podría ejecutarse más de una vez. Comprueba el estado global en tu etiqueta `<script>`, y ejecuta condicionalmente tu código cuando sea posible. Esto funciona porque `window` se mantiene.

```astro
<script is:inline>
  if (!window.SomeGlobal) {
    window.SomeGlobal = {} // ....
  }
</script>
```

Consulta el [Tutorial Añadir View Transitions](/es/tutorials/add-view-transitions/#actualiza-los-scripts) para ver un ejemplo de actualización de scripts existentes en un proyecto.

## Eventos del ciclo de vida

El enrutador `<ViewTransition />` proporciona varios eventos en el `document` durante la navegación. Estos eventos proporcionan hooks en el ciclo de vida de la navegación, permitiéndote realizar acciones como mostrar indicadores de que la nueva página está cargado, sobrescribe el comportamiento predeterminado y restablece el estado mientras se completa la navegación.

El proceso de navegación implica una fase de **preparación**, cuando el nuevo contenido es cargado; una fase de **intercambio de DOM**, donde el contenido de la página antigua se sustituye por el de la nueva; y una fase de **finalización** donde los scripts son ejecutados, la carga se informa como completada y se realiza un trabajo de limpieza.

Los eventos del ciclo de vida de la API de View Transitions de Astro, en orden, son:
- [`astro:before-preparation`](#astrobefore-preparation)
- [`astro:after-preparation`](#astroafter-preparation)
- [`astro:before-swap`](#astrobefore-swap)
- [`astro:after-swap`](#astroafter-swap)
- [`astro:page-load`](#astropage-load)

:::tip
El evento `before-` te permite influir y modificar acciones que están a punto de producirse y los `after-` son notificaciones de que se ha completado una fase.
:::

Mientras algunas acciones pueden ser disparadas durante cualquier evento, algunas tareas solo pueden realizarse durante un evento especifico para mejores resultados, como mostrar un spinner de carga antes de la preparación o sobrescribir pares de animaciones antes de intercambiar el contenido.

### `astro:before-preparation`

<p><Since v="3.6.0" /></p>

Un evento que es disparado al inicio de la fase de preparación, después de que la navegación ha comenzado (p. ej. después de que el usuario haya clicado un enlace), pero antes de que el contenido es cargado.

Este evento es usado:

- Para hacer algo antes de que la carga haya comenzado, como mostrar un spinner de carga.
- Para modificar la carga, como cargar el contenido que has definido en una plantilla en lugar de una URL externa.
- Para cambiar la `dirección` de la navegación (que suele ser `adelante` o `atrás`) para realizar una animación personalizada.

Aquí hay un ejemplo usando el evento `astro:before-preparation` para cargar un spinner antes de que se cargue el contenido y pararlo inmediatamente depués la carga.
Ten en cuenta que el uso del callback del loader de esta manera permite la ejecución asíncrona del código.

```js
<script is:inline>
  document.addEventListener('astro:before-preparation', ev => {
    const originalLoader = ev.loader;
    ev.loader = async function() {
      const { startSpinner } = await import('./spinner.js');
      const stop = startSpinner();
      await originalLoader();
      stop();
    };
  });
</script>
```

### `astro:after-preparation`

<p><Since v="3.6.0" /></p>

Un evento que es diparado al final de la fase de preparación, después de que el contenido de la nueva página haya sido cargado y analizado en un documento. Este evento ocurre antes de la fase de view transitions.

Este ejemplo usa el evento `astro:before-preparation` para comenzar un indicador de carga y el evento `astro:after-preparation` para pararlo:

```astro
<script is:inline>
  document.addEventListener('astro:before-preparation', () => {
    document.querySelector('#loading').classList.add('show');
  });
  document.addEventListener('astro:after-preparation', () => {
    document.querySelector('#loading').classList.remove('show');
  });
</script>
```

Esta es una versión más sencilla de un spinner de carga que el ejemplo mostrado anteriormente: si todo el código de los listener's puede ejecutarse de forma síncrona, no es necesario conectarse al callback del loader.

### `astro:before-swap`

<p><Since v="3.6.0" /></p>

Un evento que es disparado antes de que el nuevo documento (que se completa durante la fase de preparación) reemplace el documento actual. Este evento ocurre dentro de una view transition, donde el usuario sigue viendo una instantánea de la página anterior.

Este evento puede ser usado para realizar cambios antes de que el intercambio ocurra. La propiedad `newDocument` en el evento representa el documento entrante. Aquí hay un ejempl para asegurar que la preferencia del modo claro u oscuro del navegador en `localStorage` se traslada a la nueva página:

```astro
<script is:inline>
  function setDarkMode(document) {
    let theme = localStorage.darkMode ? 'dark' : 'light';
    document.documentElement.dataset.theme = theme;
  }
  setDarkMode(document);
  document.addEventListener('astro:before-swap', ev => {
    // Pasa el documento entrante para establecer el tema en él
    setDarkMode(ev.newDocument);
  });
</script>
```

El evento `astro:before-swap` también puede ser usado para cambiar la **implementación** del intercambio. La implementación del intercambio por defecto compara el contenido principal, mueve elementos __persistentes__ del antiguo documento al `newDocument`, y luego reemplaza todo el `body` con el body del nuevo documento. 

En este punto del ciclo de vida, podrías optar por definir tu propia implementación de intercambio, por ejemplo, para comparar todo el contenido del documento existente (como hacen algunos otros enrutadores):

```astro
<script is:inline>
  document.addEventListener('astro:before-swap', ev => {
    ev.swap = () => {
      diff(document, ev.newDocument);
    };
  });
</script>
```

### `astro:after-swap`

Un evento que se dispara inmediatamente después de que la nueva página reemplace la página antigua. Puedes escuchar este evento en el `document` y desencadenar acciones que ocurrirán antes de que se rendericen los elementos DOM de la nueva página y se ejecuten los scripts.

Este evento, cuando se escucha en la **página saliente**, es útil para pasar y restaurar cualquier estado en el DOM que necesite transferirse a la nueva página.

Este es el último punto en el ciclo de vida donde sigue siendo seguro para, por ejemplo, añadir un nombre de clase para el modo oscuro (`<html class="dark-mode">`), aunque podrías hacerlo en un evento anterior.

El evento `astro:after-swap` ocurre inmediatamente después de que el historial del navegador haya sido actualizado y la posición del scroll haya sido establecida. Por lo tanto, un uso de este evento es sobreescribir la restauración predeterminada para la navegación en el historial. El siguiente ejemplo restablece la posición del scroll horizontal y vertical en la esquina superior izquierda de la página para cada navegación.

```js
document.addEventListener('astro:after-swap', 
  () => window.scrollTo({ left: 0, top: 0, behavior: 'instant' }))
```

### `astro:page-load`

Un evento que se dispara al final de la navegación de la página, después de que la nueva página es visible para el usuario y se han cargado los estilos y scripts bloqueantes. Puedes escuchar este evento en el `document`.

El componente `<ViewTransitions />` dispara este evento se dispara tanto en la navegación inicial de la página para una página pre-renderizada como en cualquier navegación posterior, ya sea hacia delante o hacia atrás.

Puedes usar este evento para ejecutar código en cada navegación de página, o sólo una vez:

```astro "{ once: true }"
<script>
  document.addEventListener('astro:page-load', () => {
    // Esto solo se ejecuta una vez.
    setupStuff();
  }, { once: true });
</script>
```

## Accesibilidad

Habilitar la navegación del lado del cliente y animar las view transitions presentan desafíos de accesibilidad, y Astro tiene como objetivo hacer que los sitios que optan por las View Transitions sean accesibles por defecto en la medida de lo posible.

### Anuncio de ruta

<p><Since v="3.2.0" /></p>

El componente `<ViewTransitions />` incluye un anunciador de ruta para la navegación de páginas durante la navegación del lado del cliente. No se necesita configuración ni acción para habilitar esto.

Las tecnologías de asistencia permiten que los visitantes sepan que la página ha cambiado anunciando el nuevo título de la página después de la navegación. Cuando se utiliza la navegación del lado del servidor con recargas tradicionales de la página completa en el navegador, esto ocurre automáticamente después de que la nueva página se carga. En la navegación del lado del cliente, el componente `<ViewTransitions />` realiza esta acción.

Para agregar un anuncio de ruta a la navegación del lado del cliente, el componente agrega un elemento a la nueva página con el atributo `aria-live` configurado en `assertive`. Esto indica a las AT (tecnologías de asistencia) que deben anunciar inmediatamente. El componente también verifica lo siguiente, en orden de prioridad, para determinar el texto del anuncio:

- El `<title>`, si existe.
- El primer `<h1>` que encuentre.
- La `pathname` de la página.

Recomendamos encarecidamente que siempre incluyas un elemento `<title>` en cada página por razones de accesibilidad.

## `prefers-reduced-motion`

El componente `<ViewTransitions />` de Astro incluye una media query de CSS que deshabilita *todas* las animaciones de transición de vista, incluida la animación de respaldo, siempre que se detecte la configuración [`prefer-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). En su lugar, el navegador simplemente intercambiará los elementos DOM sin una animación.

## Actualizar a la v3.0 desde la v2.x

Las view transitions ya no están detrás de una bandera experimental en Astro v3.0.

Si **no** habías habilitado esta bandera experimental en Astro 2.x, esto no causará ningún cambio disruptivo en tu proyecto. La nueva API de View Transitions no afecta tu código existente.

Si anteriormente estabas utilizando view transitions experimentales, es posible que haya algunos cambios disruptivos cuando actualices tu proyecto Astro desde una versión anterior.

Por favor, sigue las instrucciones a continuación según corresponda para actualizar **un proyecto de Astro v2.x configurado con `experimental.viewTransitions: true`** a la v3.0.

### Actualizar desde `experimental.viewTransitions`

Si anteriormente habías habilitado la bandera experimental para las view transitions, deberás actualizar tu proyecto para Astro v3.0, que ahora permite las view transitions de manera predeterminada.

#### Eliminar la bandera `experimental.viewTransitions`

Elimina la bandera experimental:

```js title="astro.config.mjs" del={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
   viewTransitions: true
  }
});
```

#### Actualizar la fuente de importación

El componente `<ViewTransitions />` ha sido movido de `astro:components` a `astro:transitions`. Actualiza la fuente de importación en todas las ocurrencias de tu proyecto.

```astro title="src/layouts/BaseLayout.astro" del="astro:components" ins="astro:transitions"
---
import { ViewTransitions } from "astro:components astro:transitions"
---
<html lang="en">
  <head>
    <title>Mi Página de Inicio</title>
    <ViewTransitions />
  </head>
  <body>
    <h1>¡Bienvenido a mi sitio web!</h1>
  </body>
</html>
```


#### Actualizar directivas `transition:animate`

**Cambiado:** El valor `morph` de la directiva `transition:animate` ha sido renombrado a `initial`. Además, esta ya no es la animación por defecto. Si no se especifica ninguna directiva `transition:animate`, tus animaciones ahora serán por defecto `fade`.

1. Renombra cualquier animación `morph` a `initial`.
    ```astro title="src/components/MyComponent.astro" del="morph" ins="initial"
    <div transition:name="name" transition:animate="morph initial" />
    ```
2. Para mantener cualquier animación que previamente usara `morph` por defecto, añade explícitamente `transition:animate="initial"` a esas animaciones.

    ```astro title="src/components/MyComponent.astro" ins='transition:animate="initial"'
    <div transition:name="name" transition:animate="initial" />
    ```
3. Puedes eliminar de manera segura cualquier animación configurada explícitamente como `fade`. Esto es ahora el comportamiento por defecto:

    ```astro title="src/components/MyComponent.astro" del="transition:animate=\"fade\""
    <div transition:name="name" transition:animate="fade" />
    ```

**Añadido:** Astro también admite un nuevo valor para `transition:animate`, llamado `none`. Este valor puede ser utilizado en el elemento `<html>` de una página para desactivar las transiciones animadas de página completa en toda la página. Esto solo anulará el **comportamiento de animación predeterminado** en elementos de la página que no tengan una directiva de animación. Aún puedes establecer animaciones en elementos individuales y estas animaciones específicas ocurrirán.

4. Ahora puedes desactivar todas las transiciones predeterminadas en una página individual, animando solamente los elementos que utilicen explícitamente una directiva `transition:animate`:

    ```astro ins="transition:animate=\"none\""
    <html transition:animate="none">
      <head></head>
      <body>
        <h1>¡Hola Mundo!</h1>
      </body>
    </html>
    ```

#### Actualizar nombres de eventos

El evento `astro:load` ha sido renombrado a `astro:page-load`. Renombra todas las instancias en tu proyecto.

```astro title="src/components/MyComponent.astro" del="astro:load" ins="astro:page-load"
<script>
document.addEventListener('astro:load astro:page-load', runSetupLogic);
</script>
```

El evento `astro:beforeload` ha sido renombrado como `astro:after-swap`. Renombra todas las instancias en tu proyecto.

```astro title="src/components/MyComponent.astro" del="astro:beforeload" ins="astro:after-swap"
<script>
document.addEventListener('astro:beforeload astro:after-swap', setDarkMode);
</script>
```
